package me.work.pay.jsyl.app.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;

import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.greenrobot.eventbus.EventBus;

import me.work.pay.jsyl.R;
import me.work.pay.jsyl.app.Constants;
import me.work.pay.jsyl.app.mqtt.IGetMessageCallBack;
import me.work.pay.jsyl.app.utils.ConnectionOptionWrapper;

import com.blankj.utilcode.util.ScreenUtils;
import com.google.gson.Gson;
import com.yzy.voice.ReturnPayResult;
import com.yzy.voice.VoicePlay;

import java.text.SimpleDateFormat;

import me.work.pay.jsyl.app.utils.RxUtil;
import me.work.pay.jsyl.app.utils.Utils;
import me.work.pay.jsyl.mvp.model.AppModel;
import me.work.pay.jsyl.mvp.model.entity.Order;
import me.work.pay.jsyl.mvp.ui.activity.PayActivity;
import me.work.pay.jsyl.mvp.ui.activity.PayLandActivity;
import me.work.pay.jsyl.mvp.ui.activity.PayResultActivity;
import me.work.pay.jsyl.mvp.ui.activity.PayResultLand2Activity;
import me.work.pay.jsyl.mvp.ui.activity.PayResultLandActivity;

public class MQTTService extends Service {

    public static final String TAG = MQTTService.class.getSimpleName();

    private static MqttClient client;
    private MqttConnectOptions conOpt;

    private String host = "post-cn-v0h0fki2t03.mqtt.aliyuncs.com";
    private String userName = "ECmtNBDyhyyrKq7O";
    private String passWord = "W08/49x4SW8ha7B1Nfb7dUlvwnc=";
    private static String myTopic = "CONGMINGPAY_ARF_DEVICE_SEND";      //要订阅的主题
    private static String clientId = "GID_ARF_SEND@@@" + Constants.sn;//客户端标识
    /**
     * MQ4IOT 实例 ID，购买后控制台获取
     */
    static String instanceId = "post-cn-v0h0fki2t03";
    /**
     * 接入点地址，购买 MQ4IOT 实例，且配置完成后即可获取，接入点地址必须填写分配的域名，不得使用 IP 地址直接连接，否则可能会导致客户端异常。
     */
    static String endPoint = "post-cn-v0h0fki2t03.mqtt.aliyuncs.com";
    /**
     * 账号 accesskey，从账号系统控制台获取
     */
    private static String accessKey = "ECmtNBDyhyyrKq7O";
    /**
     * 账号 secretKey，从账号系统控制台获取，仅在Signature鉴权模式下需要设置
     */
    private static String secretKey = "tbxVBnQKseC3AQADfjqfsoJ6qCgDUv";
    /**
     * MQ4IOT clientId，由业务系统分配，需要保证每个 tcp 连接都不一样，保证全局唯一，如果不同的客户端对象（tcp 连接）使用了相同的 clientId 会导致连接异常断开。
     * clientId 由两部分组成，格式为 GroupID@@@DeviceId，其中 groupId 在 MQ4IOT 控制台申请，DeviceId 由业务方自己设置，clientId 总长度不得超过64个字符。
     */
//    String clientId = "GID_ARF_DEVICE@@@1234567890";
    /**
     * MQ4IOT 消息的一级 topic，需要在控制台申请才能使用。
     * 如果使用了没有申请或者没有被授权的 topic 会导致鉴权失败，服务端会断开客户端连接。
     */
    final String parentTopic = "CONGMINGPAY_ARF_DEVICE_SEND";
    private IGetMessageCallBack IGetMessageCallBack;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(getClass().getName(), "onCreate");
//        init();
        try {
            ConnectionOptionWrapper connectionOptionWrapper = new ConnectionOptionWrapper(instanceId, accessKey, secretKey, clientId);
            client = new MqttClient("tcp://" + endPoint + ":1883", clientId, new MemoryPersistence());
            client.setTimeToWait(5000);
            client.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    String s = "";
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) {
                    String json = message.toString();
                    String now_message = json;
                    EventBus.getDefault().post(new ReturnPayResult(3, "收到推送信息：" + now_message));
                    if (!TextUtils.isEmpty(now_message) && now_message.contains("aerf_adver_up")) {
                        EventBus.getDefault().post(new ReturnPayResult(true));
                    } else {
                        Order order = new Gson().fromJson(json, Order.class);
                        if (order.audio_type.equals("6")) {
                            VoicePlay.with(getApplicationContext()).playCancel(order.money);
                            if (PayActivity.main != null) PayActivity.main.killMyself();
                            if (PayLandActivity.main != null) PayLandActivity.main.killMyself();
                            return;
                        }
                        Class<?> aClass = PayResultActivity.class;
                        if (AppModel.getInstance().getLauncherData() != null && AppModel.getInstance().getLauncherData().isLandscape()) {
                            if (AppModel.getInstance().getLauncherData().isReverseLand()) {
                                aClass = PayResultLandActivity.class;
                            }else{
                                aClass = PayResultLand2Activity.class;
                            }

                        }
                        Intent intent = new Intent(getApplicationContext(), aClass);
                        intent.putExtra("json", json);
                        startActivity(intent);
                        long currentTime = System.currentTimeMillis();
                        String timeNow = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(currentTime);
                        EventBus.getDefault().post(new ReturnPayResult(2, "{\"sn\":" + Constants.sn + ",\"request_id\":\"" + order.request_id + "\",\"play_time\":\"" + timeNow + "\"}"));

                    }
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    String s = "";
                }
            });
            client.connect(connectionOptionWrapper.getMqttConnectOptions());
//            MqttMessage message = new MqttMessage("hello mq4Iot pub sub msg".getBytes());
//            message.setQos(0);
//            client.publish("CONGMINGPAY_ARF_DEVICE/p2p/GID_ARF_DEVICE@@@1234567890", message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void publish_get(String msg) {
        String topic = myTopic;
        Integer qos = 0;
        Boolean retained = false;
        try {
            if (client != null) {
                client.publish(topic, msg.getBytes(), qos.intValue(), retained.booleanValue());
                EventBus.getDefault().post(new ReturnPayResult(3, "给后台推送消息：" + msg));
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    static MqttClient post_client;


    public static void publish(String msg) {
        Log.i("ArmsHttpLog", "推送过来的：" + msg);
        int i = (int) (Math.random() * 900 + 100);
        String client = "GID_ARF_CONSUME@@@" + Constants.sn + i;
        Log.i("ArmsHttpLog", "推送过来的client：" + client);

        try {
            if (post_client == null) {
                ConnectionOptionWrapper connectionOptionWrapper =
                        new ConnectionOptionWrapper(instanceId, accessKey, secretKey, client);
                post_client = new MqttClient("tcp://" + endPoint + ":1883", client, new MemoryPersistence());
                post_client.setTimeToWait(5000);
                post_client.setCallback(new MqttCallback() {
                    @Override
                    public void connectionLost(Throwable cause) {
                        Log.i("ArmsHttpLog", "error:" + cause);
                    }

                    @Override
                    public void messageArrived(String topic, MqttMessage message) throws Exception {
                        String s = "";
                        Log.i("ArmsHttpLog", topic + "--" + new Gson().toJson(message));
                    }

                    @Override
                    public void deliveryComplete(IMqttDeliveryToken token) {
                        Log.i("ArmsHttpLog", "deliveryComplete:" + token);

                    }
                });
                post_client.connect(connectionOptionWrapper.getMqttConnectOptions());
            }
            String topic = "CONGMINGPAY_ARF_DEVICE_CONSUME";
            MqttMessage message = new MqttMessage(msg.getBytes());
            message.setQos(0);
            post_client.publish(topic, message);
            EventBus.getDefault().post(new ReturnPayResult(3, "给后台推送消息：" + msg));
        } catch (Exception e) {
            Log.i("ArmsHttpLog", "Exception:" + e.getMessage());
//            e.printStackTrace();
        }
    }

//    private void init() {
//        // 服务器地址（协议+地址+端口号）
//        String uri = host;
//        client = new MqttAndroidClient(this, uri, clientId);
//        // 设置MQTT监听并且接受消息
//        client.setCallback(mqttCallback);
//
//        conOpt = new MqttConnectOptions();
//        // 清除缓存
//        conOpt.setCleanSession(true);
//        // 设置超时时间，单位：秒
//        conOpt.setConnectionTimeout(10);
//        // 心跳包发送间隔，单位：秒
//        conOpt.setKeepAliveInterval(20);
//        // 用户名
//        conOpt.setUserName(userName);
//        // 密码
//        conOpt.setPassword(passWord.toCharArray());     //将字符串转换为字符串数组
//
//        // last will message
//        boolean doConnect = true;
//        String message = "{\"terminal_uid\":\"" + clientId + "\"}";
//        Log.e(getClass().getName(), "message是:" + message);
//        String topic = myTopic;
//        Integer qos = 0;
//        Boolean retained = false;
//        if ((!message.equals("")) || (!topic.equals(""))) {
//            // 最后的遗嘱
//            // MQTT本身就是为信号不稳定的网络设计的，所以难免一些客户端会无故的和Broker断开连接。
//            //当客户端连接到Broker时，可以指定LWT，Broker会定期检测客户端是否有异常。
//            //当客户端异常掉线时，Broker就往连接时指定的topic里推送当时指定的LWT消息。
//
//            try {
//                conOpt.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
//            } catch (Exception e) {
//                Log.i(TAG, "Exception Occured", e);
//                doConnect = false;
//                iMqttActionListener.onFailure(null, e);
//            }
//        }
//
//        if (doConnect) {
//            doClientConnection();
//        }
//
//    }


    @Override
    public void onDestroy() {
        stopSelf();
        try {
            client.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

    /**
     * 连接MQTT服务器
     */
    private void doClientConnection() {
//        if (!client.isConnected() && isConnectIsNormal()) {
//            try {
//                client.connect(conOpt, null, iMqttActionListener);
//            } catch (MqttException e) {
//                e.printStackTrace();
//            }
//        }

    }

    // MQTT是否连接成功
    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {

        @Override
        public void onSuccess(IMqttToken arg0) {
            Log.i(TAG, "连接成功 ");
            try {
                // 订阅myTopic话题
                client.subscribe(myTopic, 1);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            // 连接失败，重连
            doClientConnection();
        }
    };

    // MQTT监听并且接受消息
    private MqttCallback mqttCallback = new MqttCallback() {

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {

            String str1 = new String(message.getPayload());
            if (IGetMessageCallBack != null) {
                IGetMessageCallBack.setMessage(str1);
            }
            String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
            Log.i(TAG, "messageArrived:" + str1);
            Log.i(TAG, str2);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {

        }

        @Override
        public void connectionLost(Throwable arg0) {
            // 失去连接，重连
        }
    };

    /**
     * 判断网络是否连接
     */
    private boolean isConnectIsNormal() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isAvailable()) {
            String name = info.getTypeName();
            Log.i(TAG, "MQTT当前网络名称：" + name);
            return true;
        } else {
            Log.i(TAG, "MQTT 没有可用网络");
            return false;
        }
    }


    @Override
    public IBinder onBind(Intent intent) {
        Log.e(getClass().getName(), "onBind");
        return new CustomBinder();
    }

    public void setIGetMessageCallBack(IGetMessageCallBack IGetMessageCallBack) {
        this.IGetMessageCallBack = IGetMessageCallBack;
    }

    public class CustomBinder extends Binder {
        public MQTTService getService() {
            return MQTTService.this;
        }
    }

    public void toCreateNotification(String message) {
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, new Intent(this, MQTTService.class), PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);//3、创建一个通知，属性太多，使用构造器模式

        Notification notification = builder
                .setTicker("测试标题")
                .setSmallIcon(R.drawable.alipay_icon)
                .setContentTitle("")
                .setContentText(message)
                .setContentInfo("")
                .setContentIntent(pendingIntent)//点击后才触发的意图，“挂起的”意图
                .setAutoCancel(true)        //设置点击之后notification消失
                .build();
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        startForeground(0, notification);
        notificationManager.notify(0, notification);

    }
}